/*
 * AB300 device support
 */

#include <epicsStdio.h>
#include <devCommonGpib.h>

/******************************************************************************
 *
 * The following define statements are used to declare the names to be used
 * for the dset tables.   
 *
 * A DSET_AI entry must be declared here and referenced in an application
 * database description file even if the device provides no AI records.
 *
 ******************************************************************************/
#define DSET_AI     devAiAB300
#define DSET_LI     devLiAB300
#define DSET_LO     devLoAB300

#include <devGpib.h> /* must be included after DSET defines */

#define TIMEOUT     1.0    /* I/O must complete within this time */
#define TIMEWINDOW  1.0    /* Wait this long after device timeout */

/******************************************************************************
 * Strings used by the init routines to fill in the znam,onam,...
 * fields in BI and BO record types.
 ******************************************************************************/

/******************************************************************************
 * Structures used by the init routines to fill in the onst,twst,... and the
 * onvl,twvl,... fields in MBBI and MBBO record types.
 *
 * Note that the intExtSsBm and intExtSsBmStop structures use the same
 * intExtSsBmStopList and intExtSsBmStopVal lists but have a different number
 * of elements in them that they use... The intExtSsBm structure only represents
 * 4 elements,while the intExtSsBmStop structure represents 5.
 ******************************************************************************/

/******************************************************************************
 * String arrays for EFAST operations. The last entry must be 0.
 *
 * On input operations,only as many bytes as are found in the string array
 * elements are compared.  Additional bytes are ignored.
 * The first matching string  will be used as a match.
 *
 * For the input operations,the strings are compared literally!  This
 * can cause problems if the instrument is returning things like \r and \n
 * characters.  When defining input strings so you include them as well.
 ******************************************************************************/

/******************************************************************************
 * Array of structures that define all GPIB messages
 * supported for this type of instrument.
 ******************************************************************************/
static int convertPositionReply(struct gpibDpvt *pdpvt, int P1, int P2, char **P3);
static int convertStatusReply(struct gpibDpvt *pdpvt, int P1, int P2, char **P3);

static struct gpibCmd gpibCmds[] = {
    /* Param 0 -- Read SCPI identification string */
    {&DSET_LO, GPIBWRITE, IB_Q_LOW, NULL, "%d", 10, 10,
        NULL, 0, 0, NULL, NULL, "\033"},

    /* Param 1 - SCPI reset command */
    {&DSET_LO, GPIBWRITE, IB_Q_LOW, NULL, "%d", 10, 10,
        NULL, 0, 0, NULL, NULL, "\030"},

    /* Param 2 - SCPI clear status command */
    {&DSET_LI, GPIBREAD, IB_Q_LOW, "\017%c", NULL, 0, 10,
        convertPositionReply, 0, 0, NULL, NULL, "\030"},

    /* Param 3 - Read SCPI status byte */
    {&DSET_LI, GPIBREAD, IB_Q_LOW, "\017%c", NULL, 0, 10,
        convertStatusReply, 0, 0, NULL, NULL, "\030"},
};

/* The following is the number of elements in the command array above.  */
#define NUMPARAMS sizeof(gpibCmds)/sizeof(struct gpibCmd)

/******************************************************************************
 * Initialize device support parameters
 *
 *****************************************************************************/
static long init_ai(int parm)
{
    if(parm==0) {
        devSupParms.name = "devAB300";
        devSupParms.gpibCmds = gpibCmds;
        devSupParms.numparams = NUMPARAMS;
        devSupParms.timeout = TIMEOUT;
        devSupParms.timeWindow = TIMEWINDOW;
        devSupParms.respond2Writes = 2;
    }
    return(0);
}

static int
convertPositionReply(struct gpibDpvt *pdpvt, int P1, int P2, char **P3)
{
	struct longinRecord *pli = ((struct longinRecord *)(pdpvt->precord));

	printf("############################################\n");
	printf("asyn start convert\n");
	if (pdpvt->msgInputLen != 3) {
		epicsSnprintf(pdpvt->pasynUser->errorMessage,
			pdpvt->pasynUser->errorMessageSize,
				"Invalid reply");
	printf("asyn stop convert\n");

	return -1;
	}

	printf("pli->val = %d\n", pli->val);
	pli->val = pdpvt->msg[0];

	return 0;
}
static int
convertStatusReply(struct gpibDpvt *pdpvt, int P1, int P2, char **P3)
{
	struct longinRecord *pli = ((struct longinRecord *)(pdpvt->precord));
	if (pdpvt->msgInputLen != 3) {
		epicsSnprintf(pdpvt->pasynUser->errorMessage,
			pdpvt->pasynUser->errorMessageSize,
				"Invalid reply");
		return -1;
	}
	pli->val = pdpvt->msg[1];
	printf("asyn start convert\n");
	
	return 0;
}

